/**
 * Manage the cron job
 */
var xmlUtils = require('./xmlUtils.js');
var footballAPI = require('./footballAPI.js');
var game = require('./game.js');
var schedule = require('node-schedule');
var schedGroupResultDemo, schedKockResultDemo, hierarchyResultDemo, startEndLevelResultDemo;

var initCronJob = function() {
    setGroupMatchesCronJob();
    //setEndGroupCronJob();
    setStartEndLevelCronJob();
};
/**
 * create Cron job for every game on the group level
 */
var setGroupMatchesCronJob = function() {

    xmlUtils.getGroupMatches(__dirname + "/resources/schedule.xml", function(result) {

        //TODO - remove this line:
        //   result = schedGroupResultDemo;

        for (var i = 0; i < result.length; i++) {
            var match_id = result[i].match_id;
            //add 2 hours to the date time
            var matchEndDate = new Date(new Date(result[i].date).getTime() + 115 * 60 * 1000);
            var nowDate = new Date();
            if (matchEndDate > nowDate) {
                setMatchCronJob(result, i, true);
                break;
            }
        }
    });
};

/**
 * create Cron job for every game on the Knockout level
 */
var setKnockoutMatchesCronJob = function() {
    xmlUtils.getKnockoutMatches(__dirname + "/resources/schedule.xml", function(result) {

        //TODO - remove this line
        //   result = schedKockResultDemo;

        for (var i = 0; i < result.length; i++) {
            var match_id = result[i].match_id;
            //add 2 hours to the date time
            var matchEndDate = new Date(new Date(result[i].date).getTime() + 115 * 60 * 1000);
            var nowDate = new Date();
            if (matchEndDate > nowDate) {
                setMatchCronJob(result, i, false);
                break;
            }
        }
    });
};

/**
 * Set new cron job for a match
 * @param allMatches all matches , Json object.
 * @param N the Nth object(match) in allMatches
 * @param groupOrKnock boolean , true - group matche, false - knockout match
 */
var setMatchCronJob = function(allMatches, N, groupOrKnock) {

    if (N < allMatches.length) {

        if (allMatches[N].level == 20) {
            setMatchCronJob(allMatches, N + 1, groupOrKnock);
        } else {

            var match_id = allMatches[N].match_id;
            //add 2 hours to the date time
            var matchEndDate = new Date(new Date(allMatches[N].date).getTime() + 115 * 60 * 1000);
            console.log("create cron job for match_id: " + match_id + ", end date: " + matchEndDate);

            //set the cron
            var job = schedule.scheduleJob(matchEndDate, function() {

                //if the next match at the same date, sleep, non blocking, for 10 sec, and then set the cron job.
                if (N > -1 && (N + 1) < allMatches.length && new Date(allMatches[N].date).getUTCDate() == new Date(allMatches[N + 1].date).getUTCDate()) {
                    setTimeout(function() {
                        console.log("next match at the same date. sleep for 10 sec");
                        setMatchCronJob(allMatches, N + 1, groupOrKnock);
                    }, 10000);
                } else {
                    // Create new cron for next game
                    if (N > -1) {
                        setMatchCronJob(allMatches, N + 1, groupOrKnock);
                    }
                }
                var isMatchClosed = false;

                footballAPI.getMatchSummary(match_id, function(result) {

                    console.dir("match_id: " + match_id + "  started running Cron job");
                    if (result.status === "closed") {
                        console.dir("match_id: " + match_id + " is closed");

                        if (groupOrKnock) {
                            game.updateGroupMatch(result.score, match_id);
                        } else {
                            game.updateKnockoutMatch(result.level, result.score, result.winner, match_id);
                        }
                    } else if (result.status === "inprogress") {
                        var count = 0;
                        console.dir("match_id: " + match_id + " inprogress");

                        //Run this interval every 5 minutes. stop after 6 times
                        var Id = setInterval(function() {
                            console.log("From Interval:" + count);
                            count++;

                            footballAPI.getMatchSummary(match_id, function(result) {
                                if (result.status === "closed") {
                                    clearInterval(Id);

                                    if (groupOrKnock) {
                                        game.updateGroupMatch(result.score, match_id);
                                    } else {
                                        game.updateKnockoutMatch(result.level, result.score, result.winner, match_id);
                                    }
                                }

                            });
                            if (count > 8) {
                                clearInterval(Id);
                                console.warn("Over than 40 minutes past, and the game still inprogress");
                            }
                        }, 8 * 60 * 1000 //5 minutes between each interval
                        );
                    } else {
                        console.warn("Match did not start yet");
                    }
                });
            });
        }
    }
};

function setLevelPrivate(result, N, firstOrLast) {
    if (N < result.length) {
        if (firstOrLast) {

            var firstDate = new Date(new Date(result[N].first).getTime() - 60 * 60 * 1000);
            if (result[N].level == 4) {
                setKnockoutMatchesCronJob();
            }
            var nowDate = new Date();
            if (firstDate > nowDate) {
                // set cron job for the start of the level - close the bet for bettings.
                console.log("create cron job for the start of level: " + result[N].level + " Date: " + firstDate);
                var job1 = schedule.scheduleJob(firstDate, function() {
                    setLevelPrivate(result, N, false);
                    console.log("Cron job: start Level : " + result[N].level + " running");
                    game.startBetLevel();
                });
            } else {
                setLevelPrivate(result, N, false);
            }
        } else {
            var lastDate = new Date(new Date(result[N].last).getTime() + 200 * 60 * 1000);
            var nowDate = new Date();

            if (lastDate > nowDate) {
                // set cron job for the end of the level - close the bet for bettings.
                console.log("create cron for the end of the level: " + result[N].level + " Date: " + lastDate)
                var job2 = schedule.scheduleJob(lastDate, function() {
                    setLevelPrivate(result, N + 1, true);
                    console.log("Cron job: end Level : " + result[N].level + " running");
                    game.endBetLevel(result[N].level);
                });
            } else {
                setLevelPrivate(result, N + 1, true);
            }
        }
    }
}

/**
 * This function set new Cron job, which update the project when a level start/end
 */
var setStartEndLevelCronJob = function() {
    console.dir("----------- setStartEndLevelCronJob---------");

    xmlUtils.getLevelFirstLastMatchForCronJob(__dirname + '/resources/schedule.xml', function(result) {

        //TODO - remove this line
        //   result = startEndLevelResultDemo;
        setLevelPrivate(result, 0, true);
    });
};

function setGroupPrivate(result, N) {
    if (N < result.length) {
        var nowDate = new Date();
        if (result[N].tournamentName !== 'World Cup, Knockout stage') {
            var seasonEnd = new Date(result[N].season_end);
            if (seasonEnd > nowDate) {
                console.log("creating cron job for group - " + result[N].tournamentName);
                var job = schedule.scheduleJob(seasonEnd, function() {

                    console.log("cron-job: Group " + result[N].tournamentName + " ended, running");
                    game.updateGroupLevel(result[N].tournamentName);

                    if (new Date(result[N + 1].season_end).getUTCDate() == seasonEnd.getUTCDate()) {
                        setTimeout(function() {
                            console.log("cron-job: Group " + result[N + 1].tournamentName + " ended, running");
                            game.updateGroupLevel(result[N + 1].tournamentName);
                            ;
                        }, 10000);
                        setGroupPrivate(result, N + 2);
                    } else {

                        setGroupPrivate(result, N + 1);
                    }
                });
            }
        } else {
            setGroupPrivate(result, N + 1);
        }
    }
};

/**
 * This function set new Cron job, that update the project after Groups level finished
 */
var setEndGroupCronJob = function() {
    console.dir("----------- start setEndGroupCronJob---------");

    xmlUtils.getEndTimeOftournaments(__dirname + '/resources/hierarchy.xml', function(result) {

        //TODO - remove this line
        //   result = hierarchyResultDemo;
        setGroupPrivate(result, 0);
    });
};

exports.initCronJob = initCronJob;

//##########################################################################################
//####################################    Test Cron-Job ####################################
//##########################################################################################

var testCronJob = function() {

    var matchStartDate = new Date();
    var matchEndDate = new Date(matchStartDate.getTime() - 5000);
    console.dir(matchStartDate);
    console.dir(matchEndDate);
    var job = schedule.scheduleJob(matchEndDate, function() {
        console.dir("-5");
        console.dir(new Date());
    });
    var job2 = schedule.scheduleJob(matchStartDate.getTime() + 5000, function() {
        console.dir("+5");
        console.dir(new Date());
    });
};
//testCronJob();

//##########################################################################################
//####################################   Simulation Cron-Job ###############################
//##########################################################################################

var generateGroupDemoSched = function() {
    xmlUtils.getGroupMatches(__dirname + '/resources/schedule.xml', function(result) {

        var newDate = new Date();

        for (var i = 0; i < result.length; i++) {

            newDate = new Date(newDate.getTime() + 5 * 1000);

            result[i].date = newDate;
        }

        schedGroupResultDemo = result;
        setGroupMatchesCronJob();
        console.dir(result);

    });

};
var generateKnockoutDemoSched = function() {
    xmlUtils.getKnockoutMatches(__dirname + '/resources/schedule.xml', function(result) {

        var newDate = new Date(new Date().getTime() + 48 * 0.2 * 60 * 1000);
        var level = 0;
        for (var i = 0; i < result.length; i++) {

            if (result[i].level != level) {
                level = result[i].level;
                newDate = new Date(newDate.getTime() + 3 * 60 * 1000);
            }
            newDate = new Date(newDate.getTime() + 60 * 1000);
            result[i].date = newDate;
        }
        console.log(result);
        schedKockResultDemo = result;
        return result;

    });

};

var generateEndStartDemo = function() {
    xmlUtils.getLevelFirstLastMatchForCronJob(__dirname + '/resources/schedule.xml', function(result) {

        //level 0
        var newDate = new Date(new Date().getTime() + 1000);
        result[0].first = newDate;
        newDate = new Date(newDate.getTime() + 3000);
        result[0].last = newDate;

        //level 4
        newDate = new Date(newDate.getTime() + 3000);
        result[1].first = newDate;
        newDate = new Date(newDate.getTime() + 3000);
        result[1].last = newDate;

        //level 3
        newDate = new Date(newDate.getTime() + 3000);
        result[2].first = newDate;
        newDate = new Date(newDate.getTime() + 4 * 60 * 1000);
        result[2].last = newDate;

        //level 2
        newDate = new Date(newDate.getTime() + 3 * 60 * 1000);
        result[3].first = newDate;
        newDate = new Date(newDate.getTime() + 2 * 60 * 1000);
        result[3].last = newDate;

        //level 1
        newDate = new Date(newDate.getTime() + 3 * 60 * 1000);
        result[4].first = newDate;
        newDate = new Date(newDate.getTime() + 1 * 60 * 1000);
        result[4].last = newDate;

        console.log(result);

        startEndLevelResultDemo = result;
        setStartEndLevelCronJob();
    });
};

var generateDemoHierarchy = function() {
    xmlUtils.getEndTimeOftournaments(__dirname + '/resources/hierarchy.xml', function(result) {

        var newDate = new Date(new Date().getTime() + 10000);
        for (var i = 0; i < result.length; i++) {

            newDate = new Date(newDate.getTime() + 5000);
            result[i].season_end = newDate;
        }
        console.log(result);

        hierarchyResultDemo = result;
        setEndGroupCronJob();
    });

};

var initCronJobDemo = function() {
    generateGroupDemoSched();
    generateKnockoutDemoSched();
    generateDemoHierarchy();
    generateEndStartDemo();
};

initCronJob();
